home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 1.toast / Sample Code / Devices and Hardware / Display Manager / DisplayVideo / DisplayVideo.c next >
Encoding:
C/C++ Source or Header  |  2000-09-28  |  18.4 KB  |  493 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        DisplayVideo.c
  3.     
  4.     Description:DisplayVideo will display all info about all video modes supported
  5.                 by each installed video card with their attached monitor. The purpose
  6.                 of this code is to provide a sample of how developers can discover the
  7.                 bit depths and timings of multisync displays.
  8.  
  9.     Author:        EWA
  10.     Copyright:     Copyright: © 1995-1999 by Apple Computer, Inc.
  11.                 all rights reserved.
  12.     
  13.     Disclaimer:    You may incorporate this sample code into your applications without
  14.                 restriction, though the sample code has been provided "AS IS" and the
  15.                 responsibility for its operation is 100% yours.  However, what you are
  16.                 not permitted to do is to redistribute the source as "DSC Sample Code"
  17.                 after having made changes. If you're going to re-distribute the source,
  18.                 we require that you make it clear in the source that the code was
  19.                 descended from Apple Sample Code, but that you've made changes.
  20.     
  21.     Change History (most recent first):
  22.                 6/24/99    Updated for Metrowerks Codewarror Pro 2.1(KG)
  23.                 1/28/97    Updated source for Metrowerks CodeWarrior 11 Fixed up 
  24.                         formatting and generally made things nicer(EWA)
  25.                 5/24/95    New today(EWA)
  26.  
  27. */
  28.  
  29.  
  30. #include <Dialogs.h>
  31. #include <Devices.h>
  32. #include <Displays.h>
  33. #include <Errors.h>
  34. #include <FixMath.h>
  35. #include <fp.h>
  36. #include <Gestalt.h>
  37. #include <Memory.h>
  38. #include <Palettes.h>
  39. #include <PLStringFuncs.h>
  40. #include <QuickDraw.h>
  41. #include <ROMDefs.h>
  42. #include <Slots.h>
  43. #include <StdIO.h>
  44. #include <Video.h>
  45. #include <TextUtils.h>
  46. #include <Strings.h>
  47. #include <DriverServices.h>
  48.  
  49. #include <stdlib.h>
  50.  
  51. //--------------------------------------------------------------
  52. //
  53. // Internal defines, structs, typedefs, and routine declarations
  54. //
  55. //--------------------------------------------------------------
  56. struct DepthInfo {
  57.     VDSwitchInfoRec            depthSwitchInfo;            // This is the switch mode to choose this timing/depth
  58.     VPBlock                    depthVPBlock;                // VPBlock (including size, depth and format)
  59. };
  60. typedef struct DepthInfo DepthInfo;
  61.  
  62. struct ListIteratorDataRec {
  63.     unsigned long            displayModeFlags;            // 
  64.     VDSwitchInfoRec            displayModeSwitchInfo;        //
  65.     VDResolutionInfoRec        displayModeResolutionInfo;    //
  66.     VDTimingInfoRec            displayModeTimingInfo;        // Contains timing flags and such
  67.     unsigned long            depthBlockCount;            // How many depths available for a particular timing
  68.     DepthInfo                *depthBlocks;                // Array of DepthInfo
  69.     Str255                    displayModeName;            // name of the timing mode
  70. };
  71. typedef struct ListIteratorDataRec ListIteratorDataRec;
  72.  
  73. void PrintCurrentVideoSetting (GDHandle walkDevice);
  74.  
  75. void DisplayVideoSettings (void);
  76.  
  77. void PrintAvailableVideoSettingsDM1 (GDHandle walkDevice);
  78.  
  79. void PrintAvailableVideoSettingsDM2 (GDHandle walkDevice,
  80.                                 DMDisplayModeListIteratorUPP myModeIteratorProc,
  81.                                 DMListIndexType theDisplayModeCount,
  82.                                 DMListType *theDisplayModeList);
  83.  
  84. pascal void ModeListIterator (    void *userData,
  85.                                 DMListIndexType itemIndex,
  86.                                 DMDisplayModeListEntryPtr displaymodeInfo);
  87.  
  88. // routine implementations
  89. void main(void)
  90. {
  91.     DisplayVideoSettings ();
  92. }
  93.  
  94.  
  95. //--------------------------------------------------------------
  96. //
  97. // Implementation of sample code
  98. //
  99. //--------------------------------------------------------------
  100. void PrintCurrentVideoSetting (GDHandle walkDevice)
  101. {
  102.     unsigned long        displayMgrVersion;
  103.     OSErr                error = paramErr;
  104.     CntrlParam            pBlock;
  105.     VDSwitchInfoRec        switchInfo;
  106.     AuxDCEHandle        theDCE;
  107.     VDSwitchInfoRec        videoMode;        
  108.  
  109.     Gestalt(gestaltDisplayMgrVers, (long*)&displayMgrVersion);
  110.     if (displayMgrVersion >= 0x00020000)
  111.     {    // get the info the DM 2.0 way
  112.         error = DMGetDisplayMode(walkDevice, &switchInfo);
  113.         if (noErr == error)
  114.         {
  115.             printf ("Current Settings DM2 - displayMode: %d, depthMode: %d\n", switchInfo.csData, switchInfo.csMode);
  116.         }
  117.         return;
  118.     }
  119.     else
  120.     {    // get the info the DM 1.0 way
  121.         videoMode.csMode = -1;        // init to bogus value
  122.         videoMode.csData = -1;        // init to bogus value            
  123.         pBlock.ioNamePtr = nil;
  124.         pBlock.ioCRefNum = (*(walkDevice))->gdRefNum;
  125.         pBlock.csCode = cscGetCurMode;
  126.         *(Ptr *)&pBlock.csParam[0] = (Ptr)&videoMode;
  127.             
  128.         error = PBStatusSync((ParmBlkPtr )&pBlock);    // ask the driver first....since we trust it the most
  129.             
  130.         if ( noErr == error && ((-1 == videoMode.csMode) || (-1 == videoMode.csData)) )
  131.             error = statusErr;
  132.         
  133.         if (noErr != error)    // if the driver has no clue fill it videoMode by hand as a last resort
  134.         {    
  135.             theDCE = (AuxDCEHandle)GetDCtlEntry((*(walkDevice))->gdRefNum);
  136.             
  137.             if( theDCE )
  138.             {
  139.                 videoMode.csData = (unsigned char)(*theDCE)->dCtlSlotId; 
  140.                 videoMode.csMode = (*(walkDevice))->gdMode;
  141.                 error = noErr;
  142.             }
  143.         }
  144.         if (noErr == error)
  145.         {
  146.             printf ("Current Settings DM1 - displayMode: %d, depthMode: %d\n", videoMode.csData, videoMode.csMode);
  147.         }
  148.         return;
  149.     }
  150. }
  151.  
  152.  
  153. void DisplayVideoSettings (void)
  154. {
  155.     Boolean                            displayMgrPresent;
  156.     short                            iCount = 0;                    // just a counter of GDevices we have seen
  157.     DMDisplayModeListIteratorUPP    myModeIteratorProc = nil;    // for DM2.0 searches
  158.     SpBlock                            spBlock;
  159.     Boolean                            suppliedGDevice;    
  160.     DisplayIDType                    theDisplayID;                // for DM2.0 searches
  161.     DMListIndexType                    theDisplayModeCount;        // for DM2.0 searches
  162.     DMListType                        theDisplayModeList;            // for DM2.0 searches
  163.     long                            value = 0;
  164.     GDHandle                        walkDevice = nil;            // for everybody
  165.  
  166.     Gestalt(gestaltDisplayMgrAttr,&value);
  167.     displayMgrPresent=value&(1<<gestaltDisplayMgrPresent);
  168.     displayMgrPresent=displayMgrPresent && (SVersion(&spBlock)==noErr);    // need slot manager
  169.     if (displayMgrPresent)                                                // and Display Manager
  170.     {    
  171.         walkDevice = DMGetFirstScreenDevice (dmOnlyActiveDisplays);            // for everybody
  172.         suppliedGDevice = false;
  173.         
  174.         myModeIteratorProc = NewDMDisplayModeListIteratorProc(ModeListIterator);    // for DM2.0 searches
  175.     
  176.         // Note that we are hosed if somebody changes the gdevice list behind our backs while we are iterating....
  177.         // ...now do the loop if we can start
  178.         if( walkDevice && myModeIteratorProc) do // start the search
  179.         {
  180.             iCount++;        // GDevice we are looking at (just a counter)
  181.             printf("=================================================\n");
  182.             printf("GDevice #%d (0x%X) at location (%d,%d).\n",iCount, *walkDevice, (long )(*walkDevice)->gdRect.left, (long )(*walkDevice)->gdRect.top);
  183.             printf("=================================================\n\n");
  184.  
  185.             PrintCurrentVideoSetting (walkDevice);
  186.             
  187.             if( noErr == DMGetDisplayIDByGDevice( walkDevice, &theDisplayID, false ) )    // DM1.0 does not need this, but it fits in the loop
  188.             {
  189.                 theDisplayModeCount = 0;    // for DM2.0 searches
  190.                 if (noErr == DMNewDisplayModeList(theDisplayID, 0, 0, &theDisplayModeCount, &theDisplayModeList) )
  191.                 {
  192.                     // search NuBus & PCI the new kool way through Display Manager 2.0
  193.                 //    printf("\nAvailable Video Settings DM2.0 way\n");
  194.                     PrintAvailableVideoSettingsDM2 (walkDevice, myModeIteratorProc, theDisplayModeCount, &theDisplayModeList);
  195.                     DMDisposeList(theDisplayModeList);    // now toss the lists for this gdevice and go on to the next one
  196.                 }
  197.                 else
  198.                 {
  199.                     // search NuBus only the old disgusting way through the slot manager
  200.                     printf("\nAvailable Video Settings DM1.0 way\n");
  201.                     PrintAvailableVideoSettingsDM1 (walkDevice);
  202.                 }
  203.             }
  204.  
  205.             printf("\n\n\n");
  206.  
  207.         } while ( !suppliedGDevice && nil != (walkDevice = DMGetNextScreenDevice ( walkDevice, dmOnlyActiveDisplays )) );    // go until no more gdevices
  208.         if( myModeIteratorProc )
  209.             DisposeRoutineDescriptor(myModeIteratorProc);
  210.         return;
  211.     }
  212. }
  213.  
  214. void PrintAvailableVideoSettingsDM1 (GDHandle walkDevice)
  215. {
  216.     AuxDCEHandle myAuxDCEHandle;
  217.     unsigned long    depthMode;
  218.     unsigned long    displayMode;
  219.     OSErr            error;
  220.     OSErr            errorEndOfTimings;
  221.     short            height;
  222.     short            jCount = 0;
  223.     Boolean            modeOk;
  224.     SpBlock            spAuxBlock;
  225.     SpBlock            spBlock;
  226.     unsigned long    switchFlags;
  227.     VPBlock            *vpData;
  228.     short            width;
  229.  
  230.     myAuxDCEHandle = (AuxDCEHandle) GetDCtlEntry((**walkDevice).gdRefNum);    
  231.     spBlock.spSlot = (**myAuxDCEHandle).dCtlSlot;
  232.     spBlock.spID = (**myAuxDCEHandle).dCtlSlotId;
  233.     spBlock.spExtDev = (**myAuxDCEHandle).dCtlExtDev;
  234.     spBlock.spHwDev = 0;                                // we are going to get this pup
  235.     spBlock.spParamData = 1<<foneslot;                    // this slot, enabled, and it better be here.
  236.     spBlock.spTBMask = 3;                                // don't have constants for this yet
  237.     errorEndOfTimings = SGetSRsrc(&spBlock);            // get the spDrvrHW so we know the ID of this puppy. This is important
  238.                                                         // since some video cards support more than one display, and the spDrvrHW
  239.                                                         // ID can, and will, be used to differentiate them.
  240.     
  241.     if ( noErr == errorEndOfTimings )
  242.     {
  243.         // reinit the param block for the SGetTypeSRsrc loop, keep the spDrvrHW we just got
  244.         spBlock.spID = 0;                                // start at zero, 
  245.         spBlock.spTBMask = 2;                            // 0b0010 - ignore DrvrSW - why ignore the SW side? Is it not important for video?
  246.         spBlock.spParamData = (1<<fall) + (1<<foneslot) + (1<<fnext);    // 0b0111 - this slot, enabled or disabled, so we even get 640x399 on Blackbird
  247.         spBlock.spCategory=catDisplay;
  248.         spBlock.spCType=typeVideo;
  249.         errorEndOfTimings = SGetTypeSRsrc(&spBlock);    // but only on 7.0 systems, not a problem since we require DM1.0
  250.         
  251.         // now, loop through all the timings for this GDevice
  252.         if ( noErr == errorEndOfTimings ) do
  253.         {
  254.             // now, loop through all possible depth modes for this timing mode
  255.             displayMode = (unsigned char)spBlock.spID;    // "timing mode, ie:resource ref number"
  256.             for (jCount = firstVidMode; jCount<= sixthVidMode; jCount++)
  257.             {
  258.                 depthMode = jCount;        // vid mode
  259.                 error = DMCheckDisplayMode(walkDevice,displayMode,depthMode,&switchFlags,0,&modeOk);
  260.     
  261.                 // only if the mode okay
  262.                 if (noErr == error && modeOk)
  263.                 {
  264.                     // have a good displayMode/depthMode combo - now lets look inside
  265.                     spAuxBlock = spBlock;                // don't ruin the iteration spBlock!!
  266.                     spAuxBlock.spID = depthMode;        // vid mode
  267.                     error=SFindStruct(&spAuxBlock);        // get back a new spsPointer
  268.                     if (noErr == error)                    // keep going if no error…
  269.                     {
  270.                         spAuxBlock.spID = 0x01;            // mVidParams request
  271.                         error=SGetBlock (&spAuxBlock);    // use the new spPointer and get back...a NewPtr'ed spResult
  272.                         if (noErr == error)                // …keep going if no error…
  273.                         {                                // We have data! lets have a look
  274.                             vpData = (VPBlock*)spAuxBlock.spResult;
  275.                             height = vpData->vpBounds.bottom;    // left and top are usually zero
  276.                             width = vpData->vpBounds.right;
  277.                             
  278.                             // print screen data
  279.                             printf("\nTiming Mode: %d\n", displayMode);
  280.                             printf("Depth Mode: %d, Depth: %d, Resolution: %dH x %dV\n",
  281.                                 depthMode,
  282.                                 vpData->vpPixelSize,
  283.                                 vpData->vpBounds.right,
  284.                                 vpData->vpBounds.bottom);
  285.                             printf("Components per Pixel: %d, bits per Component: %d\n",
  286.                                 vpData->vpCmpCount,
  287.                                 vpData->vpCmpSize);
  288.                             printf("Switch flags:\n");
  289.                             if (switchFlags & 1<<kNoSwitchConfirmBit)
  290.                                 printf("      Confirmation not required,\n");
  291.                             else
  292.                                 printf("      Confirmation required,\n");
  293.                             if (switchFlags & 1<<kDepthNotAvailableBit)
  294.                                 printf("      Current depth not available in this mode,\n");
  295.                             else
  296.                                 printf("      Current depth available in this mode,\n");
  297.                             if (switchFlags & 1<<kShowModeBit)
  298.                                 printf("      Always shown,\n");
  299.                             else
  300.                                 printf("      Not always shown,\n");
  301.                             if (switchFlags & 1<<kModeNotResizeBit)
  302.                                 printf("      Not resizeable,\n");
  303.                             else
  304.                                 printf("      Resizeable\n");
  305.  
  306.                             if (spAuxBlock.spResult) DisposePtr ((Ptr)spAuxBlock.spResult);    // toss this puppy when done
  307.                         }
  308.                     }
  309.                 }
  310.             }
  311.             // go around again, looking for timing modes for this GDevice
  312.             spBlock.spTBMask = 2;        // ignore DrvrSW
  313.             spBlock.spParamData =  (1<<fall) + (1<<foneslot) + (1<<fnext);    // next resource, this slot, whether enabled or disabled
  314.             errorEndOfTimings = SGetTypeSRsrc(&spBlock);    // and get the next timing mode
  315.         } while ( noErr == errorEndOfTimings );    // until the end of this GDevice
  316.     }
  317.  
  318. }
  319.  
  320. pascal void ModeListIterator(void *userData, DMListIndexType, DMDisplayModeListEntryPtr displaymodeInfo)
  321. {
  322.     unsigned long            depthCount;
  323.     short                    iCount;
  324.     ListIteratorDataRec        *myIterateData        = (ListIteratorDataRec*) userData;
  325.     DepthInfo                *myDepthInfo;
  326.     
  327. // printf ("\n now in ModeListIterator\n");
  328.     // set display data in a round about way
  329.     // Set the basics
  330.     myIterateData->displayModeFlags                = displaymodeInfo->displayModeFlags;        // Info on this particular display mode
  331.     myIterateData->displayModeSwitchInfo        = *displaymodeInfo->displayModeSwitchInfo;    // not needed - depth info has this per depth
  332.     myIterateData->displayModeResolutionInfo    = *displaymodeInfo->displayModeResolutionInfo;    // refresh rate, pixels/lines at max depth 
  333.     myIterateData->displayModeTimingInfo        = *displaymodeInfo->displayModeTimingInfo;    // to get the flags on timing mode
  334.     PStrCopy ((StringPtr)&myIterateData->displayModeName, (ConstStr255Param)*displaymodeInfo->displayModeName);    // the name of the mode
  335.     
  336.     // now get the DMDepthInfo into memory we own
  337.     depthCount = displaymodeInfo->displayModeDepthBlockInfo->depthBlockCount;
  338.     myDepthInfo = (DepthInfo*)NewPtrClear(depthCount * sizeof(DepthInfo));
  339.  
  340.     // set the info for the caller
  341.     myIterateData->depthBlockCount = depthCount;
  342.     myIterateData->depthBlocks = myDepthInfo;
  343.  
  344.     // and fill out all the entries
  345.     if (depthCount) for (iCount=0; iCount < depthCount; iCount++)
  346.     {
  347.         myDepthInfo[iCount].depthSwitchInfo = 
  348.             *displaymodeInfo->displayModeDepthBlockInfo->depthVPBlock[iCount].depthSwitchInfo;
  349.         myDepthInfo[iCount].depthVPBlock = 
  350.             *displaymodeInfo->displayModeDepthBlockInfo->depthVPBlock[iCount].depthVPBlock;
  351.     }
  352. }
  353.  
  354. void PrintAvailableVideoSettingsDM2 (GDHandle walkDevice,
  355.                             DMDisplayModeListIteratorUPP myModeIteratorProc,
  356.                             DMListIndexType theDisplayModeCount,
  357.                             DMListType *theDisplayModeList)
  358. {
  359.     short                    jCount;
  360.     short                    kCount;
  361.     ListIteratorDataRec        searchData;
  362.     double_t                refreshRate;
  363.     unsigned long            switchFlags;
  364.     Boolean                    modeOk;
  365.     OSErr                    error;
  366.  
  367.     searchData.depthBlocks = nil;
  368.     // get the mode lists for this GDevice
  369. // printf ("\n about to start DMGetIndexedDisplayModeFromList loop\n");
  370.     for (jCount=0; jCount<theDisplayModeCount; jCount++)        // get info on all the resolution timings
  371.     {
  372.         DMGetIndexedDisplayModeFromList(*theDisplayModeList, jCount, 0, myModeIteratorProc, &searchData);
  373. // printf ("\n just did a DMGetIndexedDisplayModeFromList\n");
  374.         
  375.         // only if the mode is valid
  376. //        if    (searchData.displayModeTimingInfo.csTimingFlags & 1<<kModeValid)
  377.         {
  378.             // for all the depths for this resolution timing (mode)...
  379.             printf("\nTiming mode: %d (or  0x%X) named “%s”\n",
  380.                         searchData.depthBlocks[0].depthSwitchInfo.csData,
  381.                         searchData.depthBlocks[0].depthSwitchInfo.csData,
  382.                         P2CStr(searchData.displayModeName));
  383.         
  384.             refreshRate = Fix2X (searchData.displayModeResolutionInfo.csRefreshRate);
  385.             refreshRate = round (refreshRate);
  386.             if (refreshRate == 0)
  387.                 printf ("Refresh rate: 0 (not defined in displayModeResolutionInfo.csRefreshRate)\n");
  388.             else
  389.                 printf ("Refresh rate: %g\n", refreshRate);
  390.             
  391.             if (searchData.displayModeResolutionInfo.csResolutionFlags & 1<<kResolutionHasMultipleDepthSizes)
  392.                 printf("DisplayMode has different H&V per bit depth\n");
  393.             else
  394.                 printf("DisplayMode does not have different H&V per bit depth\n");
  395.  
  396.             {
  397.                 char        tempArr[6];
  398.                 ResType*    tempPtr = (ResType* )&tempArr[0];                    // Make a convenient ptr to assign the restype
  399.                 *tempPtr = searchData.displayModeTimingInfo.csTimingFormat;        // contents of string are the resType
  400.                 tempArr[4] = 0;                                                    // null temp the string
  401.                 printf("Timing format: “%s”. Timing csData %d\n", tempArr, searchData.displayModeTimingInfo.csTimingData);
  402.             }
  403.             
  404.             printf("Available depths:\n");
  405.  
  406.  
  407.             if (searchData.depthBlockCount) for (kCount = 0; kCount < searchData.depthBlockCount; kCount++)
  408.             {
  409.                 // print all the timing information 
  410.                 printf("    Depth: %d, Depth mode: 0x%X, Resolution: %dH x %dV\n",
  411.                     searchData.depthBlocks[kCount].depthVPBlock.vpPixelSize,
  412.                     searchData.depthBlocks[kCount].depthSwitchInfo.csMode,
  413.                     searchData.depthBlocks[kCount].depthVPBlock.vpBounds.right,
  414.                     searchData.depthBlocks[kCount].depthVPBlock.vpBounds.bottom);
  415.         //        printf("Components per Pixel: %d, bits per Component: %d\n",
  416.         //            searchData.depthBlocks[kCount].depthVPBlock.vpCmpCount,
  417.         //            searchData.depthBlocks[kCount].depthVPBlock.vpCmpSize);
  418.                     
  419.  
  420.             }
  421.             
  422.             error = DMCheckDisplayMode(walkDevice,
  423.                         searchData.depthBlocks[0].depthSwitchInfo.csData,
  424.                         searchData.depthBlocks[0].depthSwitchInfo.csMode,
  425.                         &switchFlags,
  426.                         0,
  427.                         &modeOk);
  428.                         
  429.             if (noErr == error && modeOk)
  430.             {
  431.                 printf("Switch flags = 0x%X\n", switchFlags);
  432.                 if (switchFlags & 1<<kNoSwitchConfirmBit)
  433.                     printf("      Confirmation not required,\n");
  434.                 else
  435.                     printf("      Confirmation required,\n");
  436.                 if (switchFlags & 1<<kDepthNotAvailableBit)
  437.                     printf("      Current depth not available in this mode,\n");
  438.                 else
  439.                     printf("      Current depth available in this mode,\n");
  440.                 if (switchFlags & 1<<kShowModeBit)
  441.                     printf("      Always shown,\n");
  442.                 else
  443.                     printf("      Not always shown,\n");
  444.                 if (switchFlags & 1<<kModeNotResizeBit)
  445.                     printf("      Not resizeable,\n");
  446.                 else
  447.                     printf("      Resizeable\n");
  448.             }
  449.  
  450.             // timing flags
  451.             printf("Timing flags = 0x%X\n",searchData.displayModeTimingInfo.csTimingFlags);
  452.             if (searchData.displayModeTimingInfo.csTimingFlags & 1<<kModeValid)
  453.                 printf("      Valid,\n",searchData.displayModeTimingInfo.csTimingFlags);
  454.             else
  455.                 printf("      Invalid,\n",searchData.displayModeTimingInfo.csTimingFlags);
  456.             if (searchData.displayModeTimingInfo.csTimingFlags & 1<<kModeSafe)
  457.                 printf("      Safe,\n");
  458.             else
  459.                 printf("      Unsafe,\n");
  460.                     if (searchData.displayModeTimingInfo.csTimingFlags & 1<<kModeDefault)
  461.                 printf("      Default,\n");
  462.             else
  463.                 printf("      Not default,\n");
  464.                     if (searchData.displayModeTimingInfo.csTimingFlags & 1<<kModeShowNow)
  465.                 printf("      Always shown,\n");
  466.             else
  467.                 printf("      Not always shown,\n");
  468.             if (searchData.displayModeTimingInfo.csTimingFlags & 1<<kModeNotResize)
  469.                 printf("      Not resizeable,\n");
  470.             else
  471.                 printf("      Resizeable,\n");
  472.             if (searchData.displayModeTimingInfo.csTimingFlags & 1<<kModeRequiresPan)
  473.                 printf("      Requires pan.\n");
  474.             else
  475.                 printf("      No pan.\n");
  476.                 
  477.             // mode flags
  478.             printf("Mode flags = 0x%X\n",searchData.displayModeFlags);
  479.             if (searchData.displayModeFlags & 1<<0)
  480.                 printf("      Stripped,\n");
  481.             else
  482.                 printf("      Not Stripped,\n");
  483.         }
  484.  
  485.         if (searchData.depthBlocks)
  486.         {
  487.             DisposePtr ((Ptr)searchData.depthBlocks);    // toss for this timing mode of this gdevice
  488.             searchData.depthBlocks = nil;                // init it just so we know
  489.         }
  490.     }
  491. }
  492.  
  493.